#pragma once

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <cstdint>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <thread>
#include <mutex>
#include <typeinfo>
#include <condition_variable>
#include <signal.h>
#include <memory>
#include <functional>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/timerfd.h>
#include <fcntl.h>
#include <unistd.h>

#define INFO 0
#define DELETE 1
#define ERROR 2
#define LOG_LEVEL ERROR 
		// 2    >=    2   break
		// 1    >=   2    break
		// 0    >=   2    break
#define LOG(level,format,...) do{\
		if(level <= LOG_LEVEL) break;\
		time_t t = time(NULL);\
		struct tm *timeinfo = localtime(&t);\
		char buffer[32] = {0};\
		strftime(buffer,31,"%Y-%m-%d %H:%M:%S",timeinfo);\
		fprintf(stdout,"[%p %s %s:%d] " format "\n", (void*)pthread_self() ,buffer,__FILE__,__LINE__,##__VA_ARGS__);\
}while(0)

#define INF_LOG(format,...) LOG(INFO,format,##__VA_ARGS__)
#define DEL_LOG(format,...) LOG(DELETE,format,##__VA_ARGS__)
#define ERR_LOG(format,...) LOG(ERROR,format,##__VA_ARGS__)

#define BUFFER_DEFAULT_SIZE 1024
class Buffer
{
public:
	Buffer()
		: _write_idx(0), _read_idx(0), _buffer(BUFFER_DEFAULT_SIZE)
	{
	}
	// ======================== 对外接口（业务流程：写入并推进、读取并弹出等） ========================
	// 写入位置地址
	char *WritePosition()
	{
		return Begin() + _write_idx;
	}
	// 读取位置地址
	char *ReadPosition()
	{
		return Begin() + _read_idx;
	}
	// 可读数据大小
	uint64_t ReadableSize()
	{
		return _write_idx - _read_idx;
	}
	// 写入数据并压入
	void WriteAndPush(const void *data, uint64_t len)
	{
		if (data == nullptr || len == 0)
		{
			return;
		}
		Write(data, len);
		MoveWriteOffset(len);
	}
	// 写入字符串数据并压入
	void WriteStringAndPush(const std::string &data)
	{
		WriteString(data);
		MoveWriteOffset(data.size());
	}
	// 写入buffer类数据并压入
	void WriteBufferAndPush(Buffer &data)
	{
		WriteBuffer(data);
		MoveWriteOffset(data.ReadableSize());
	}
	// 读取数据并弹出
	void ReadAndPop(void *buff, uint64_t len)
	{
		Read(buff, len);
		MoveReadOffset(len);
	}
	// 读取字符串数据并弹出
	std::string ReadStringAndPop(uint64_t len)
	{
		assert(len <= ReadableSize()); // 读取数据大小必须小于可读数据大小
		std::string str = ReadString(len);
		MoveReadOffset(len);
		return str;
	}

	// 获取一行缓冲区数据并弹出
	std::string GetLineBufferAndPop()
	{
		std::string str = GetLineBuffer();
		MoveReadOffset(str.size());
		return str;
	}
	// 清空缓冲区
	void Clear()
	{
		_write_idx = 0;
		_read_idx = 0;
	}
	// ======================== 偏移操作（修改读写偏移，依赖空间计算） ========================
	// 读偏移量向后移动
	void MoveReadOffset(uint64_t len)
	{
		// 读向后偏移大小必须小于可读数据大小
		assert(len <= ReadableSize());
		_read_idx += len;
	}
	// 写偏移量向后移动
	void MoveWriteOffset(uint64_t len)
	{
		// 写向后移动偏移大小必须小于后面空闲大小
		assert(len <= TailIdleSize());
		_write_idx += len;
	}

private:
	// ======================== 底层工具函数（纯辅助，不涉及业务） ========================
	char *Begin()
	{
		return &*_buffer.begin();
	}
	// ======================== 空间计算工具（基于工具函数，计算空闲/可读空间） ========================
	// 末尾剩余空间大小
	uint64_t TailIdleSize()
	{
		return _buffer.size() - _write_idx;
	}
	// 起始剩余空间大小
	uint64_t HeadIdleSize()
	{
		return _read_idx;
	}
	// ======================== 核心逻辑（空间确保、实际读写） ========================
	// 确保写入空间足够，末尾剩余空间大小加上起始空间剩余大小
	void EnsureWriteSpace(uint64_t len)
	{
		if (len < TailIdleSize()) // 末尾空间足够
		{
			return;
		}
		else if (len <= TailIdleSize() + HeadIdleSize()) // 末尾空闲空间不够，则判断加上起始位置的空闲空间大小是否足够, 够了就将数据移动到起始位置
		{
			// 移动数据到最开始
			uint64_t res = ReadableSize();						 // 保存当前可读数据大小，后边方便修改偏移量
			std::copy(ReadPosition(), WritePosition(), Begin()); // 把可读数据拷贝到起始位置
			_read_idx = 0;										 // 读偏移量归零
			_write_idx = res;									 // 将写位置置为可读数据大小， 因为当前的可读数据大小就是写偏移量
		}
		else // //总体空间不够，则需要扩容，不移动数据，直接给写偏移之后扩容足够空间即可
		{
			// uint64_t newcapacity = std::max(_buffer.size() * 2, _write_idx + len);
			_buffer.resize(_write_idx + len); // 扩容
			INF_LOG("resize: %ld", _write_idx + len);
		}
	}
	// 写入数据
	void Write(const void *data, uint64_t len)
	{
		if (data == nullptr)
		{
			return;
		}
		EnsureWriteSpace(len);
		const char *da = (const char *)data;
		std::copy(da, da + len, WritePosition());
	}
	// 读取数据
	void Read(void *buff, uint64_t len)
	{
		assert(len <= ReadableSize()); // 读取数据大小必须小于可读数据大小
		std::copy(ReadPosition(), ReadPosition() + len, (char *)buff);
	}
	// ======================== 业务适配（基于核心逻辑，封装字符串、Buffer 读写） ========================
	// 写入字符串数据
	void WriteString(const std::string &data)
	{
		return Write(data.c_str(), data.size());
	}
	// 写入buffer类数据
	void WriteBuffer(Buffer &data)
	{
		return Write(data.ReadPosition(), data.ReadableSize());
	}
	// 读取字符串数据
	std::string ReadString(uint64_t len)
	{
		assert(len <= ReadableSize()); // 读取数据大小必须小于可读数据大小
		std::string str;
		str.resize(len);
		Read(&str[0], len);
		return str;
	}
	// 查找一行数据的结尾\n
	char *FindCRLF()
	{
		char *f = (char *)memchr(ReadPosition(), '\n', ReadableSize());
		return f;
	}
	// 获取一行缓冲区数据
	std::string GetLineBuffer()
	{
		char *pos = FindCRLF();
		if (pos == nullptr)
			return "";
		return ReadString(pos - ReadPosition() + 1); // 要把\n取出来 ,不然下次取一行数据为空
	}

private:
	std::vector<char> _buffer; // 缓冲区
	uint64_t _read_idx;		   // 读偏移量
	uint64_t _write_idx;	   // 写偏移量
};



class EventLoop;
using EventCallback = std::function<void()>;
class Channel
{
public:
	Channel(EventLoop *loop, int fd)
		: _loop(loop), _fd(fd), _event(0), _revent(0)
	{
	}
	int Fd()
	{
		return _fd;
	}
	uint32_t Events()
	{
		return _event; // 获取想要监控的事件
	}
	void SetRevent(uint32_t events)
	{
		_revent = events; // 设置实际就绪的事件
	}
	// 描述符是否可写
	bool Writeable()
	{
		return _event & EPOLLOUT; // 都是1 才是1
	}
	// 描述符是否可读
	bool Readable()
	{
		return _event & EPOLLIN;
	}
	// 开启可读事件
	void EnableReadableEvent()
	{
		_event |= EPOLLIN; // 只要为1，就为1
						   // 后续会添加到eventloop中
		Update();
	}
	// 开启可写事件
	void EnableWriteableEvent()
	{
		_event |= EPOLLOUT;
		// 后续会添加到eventloop中
		Update();
	}
	// 解除可读事件监控
	void CloseReadableEvent()
	{
		_event &= ~EPOLLIN;
		// 后续会添加到eventloop中
		Update();
	}
	// 解除可写事件监控
	void CloseWriteableEvent()
	{
		_event &= ~EPOLLOUT;
		// 后续会添加到eventloop中
		Update();
	}
	// 解除所有事件监控
	void CloseAllEvent()
	{
		_event = 0;
		// 后续会添加到eventloop中
		Update();
	}
	// 移除监控
	void Remove();
	void Update();
	// 事件处理，一旦有事件触发了，就调用这个函数，来执行各个回调函数
	void HandlerEvent()
	{
		// EPOLLIN(普通可读事件) EPOLLRDHUP(对端半关闭或关闭连接) EPOLLPRI(紧急数据可读,优先数据)
		// EPOLLOUT (写事件) EPOLLERR (错误事件) EPOLLHUP (挂断事件)
		if ((_revent & EPOLLIN) || (_revent & EPOLLRDHUP) || (_revent & EPOLLPRI))
		{
			if (_read_callback)
			{
				DEL_LOG("触发可读事件,描述符：%d", _fd);
				_read_callback();
			}
		}
		if ((_revent & EPOLLOUT))
		{
			if (_write_callback)
			{
				DEL_LOG("触发写事件,描述符：%d", _fd);
				_write_callback();
			}
		}
		else if ((_revent & EPOLLERR))
		{
			if (_error_callback)
			{
				DEL_LOG("触发异常事件,描述符：%d", _fd);
			}
		}
		else if ((_revent & EPOLLHUP))
		{
			if (_close_callback)
			{
				DEL_LOG("触发链接关闭事件,描述符：%d", _fd);
				_close_callback();
			}
		}
		// 可以直接放到最后，不用担心因为释放连接了还要进行操作而造成崩溃，因为释放操作放到了任务队列中
		if (_event_callback)
		{
			DEL_LOG("触发任意事件,描述符：%d", _fd);
			_event_callback();
		}
	}
	// 设置可读事件回调
	void SetReadCallback(const EventCallback &cb)
	{
		_read_callback = cb;
	}
	// 设置可写事件回调
	void SetWriteCallback(const EventCallback &cb)
	{
		_write_callback = cb;
	}
	// 设置错误事件回调
	void SetErrorCallback(const EventCallback &cb)
	{
		_error_callback = cb;
	}
	// 设置挂断事件回调
	void SetCloseCallback(const EventCallback &cb)
	{
		_close_callback = cb;
	}
	// 设置任意事件回调
	void SetEventCallback(const EventCallback &cb)
	{
		_event_callback = cb;
	}
	EventLoop *Loop()
	{
		return _loop;
	}

private:
	EventLoop *_loop;
	int _fd;
	uint32_t _event;			   // 当前需要监控的事件
	uint32_t _revent;			   // 当前链接触发的事件
	EventCallback _read_callback;  // 可读事件回调
	EventCallback _write_callback; // 可写事件回调
	EventCallback _error_callback; // 错误事件回调
	EventCallback _close_callback; // 挂断事件回调
	EventCallback _event_callback; // 任意事件回调
};



#define LISTEN_DEFAULT_BACKLOG 1024
class Socket
{
public:
	Socket()
		: _sockfd(-1)
	{
	}
	Socket(int sockfd)
		: _sockfd(sockfd)
	{
	}
	~Socket()
	{
		Close();
	}
	int Fd()
	{
		return _sockfd;
	}
	// 向客服端链接新链接
	int Accept()
	{
		int newfd = ::accept(_sockfd, nullptr, nullptr); // 不关心链接信息
		if (newfd < 0)
		{
			ERR_LOG("accept error, %d%s", errno, strerror(errno));
			return -1;
		}
		return newfd;
	}
	// 创建服务端链接
	bool CreateTcpServer(uint16_t port, bool flag = false) // false为不开启非阻塞 true为开启阻塞
	{
		// 创建套接字 绑定地址信息  监听 设置非阻塞 开始地址复用
		if (!Create())
		{
			return false;
		}
		EnableAddressAndPortReuse();
		if (flag)
			SetNonBlock();
		if (!Bind(port))
		{
			return false;
		}
		if (!Listen())
		{
			return false;
		}
		return true;
	}
	// 创建客服端链接
	bool CreateTcpClient(const std::string &ip, uint16_t port)
	{
		// 创建套接字 发起链接
		if (!Create())
		{
			return false;
		}
		if (!Connect(ip, port))
		{
			return false;
		}
		return true;
	}
	ssize_t Recv(void *buf, size_t len, int flag = 0) // 默认是0 阻塞读取
	{
		ssize_t ret = ::recv(_sockfd, buf, len, flag);
		if (ret == 0)
		{
			INF_LOG("链接断开了，%d%s", errno, strerror(errno));
			return -1;
		}
		if (ret < 0)
		{
			// EAGAIN 和 EWOULDBLOCK 表示没有数据可读
			// EINTR 表示被信号中断
			if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
			{
				return 0; // 表示这次接收没有接收到数据
			}
			ERR_LOG("recv error, %d%s", errno, strerror(errno));
			return -1;
		}
		return ret; // 返回读取数据长度
	}
	ssize_t Send(const void *buf, size_t len, int flag = 0)
	{
		ssize_t ret = ::send(_sockfd, buf, len, flag);
		if (ret < 0)
		{
			if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
			{
				return 0; // 表示这次接收没有发送数据
			}
			ERR_LOG("send error, %d%s", errno, strerror(errno));
			return -1;
		}
		return ret; // 返回发送的数据长度
	}
	ssize_t RecvNonBlock(void *buf, size_t len)
	{
		return Recv(buf, len, MSG_DONTWAIT); // MSG_DONTWAIT 表示当前接收为非阻塞。
	}
	ssize_t SendNonBlock(const void *buf, size_t len)
	{
		if (len == 0)
			return 0;
		return Send(buf, len, MSG_DONTWAIT); // MSG_DONTWAIT 表示当前发送为非阻塞。
	}
	// 关闭套接字
	void Close()
	{
		if (_sockfd != -1)
		{
			::close(_sockfd);
			_sockfd = -1;
		}
	}

private:
	// 创建套接字
	bool Create()
	{
		_sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
		if (_sockfd == -1)
		{
			ERR_LOG("socket error, %d%s", errno, strerror(errno));
			return false;
		}
		return true;
	}
	// 绑定地址信息
	bool Bind(uint16_t port)
	{
		struct sockaddr_in addr;
		memset(&addr, 0, sizeof(addr));
		addr.sin_family = AF_INET;
		addr.sin_port = ::htons(port);
		addr.sin_addr.s_addr = INADDR_ANY;
		socklen_t len = sizeof(addr);
		int ret = ::bind(_sockfd, (sockaddr *)&addr, len);
		if (ret < 0)
		{
			ERR_LOG("bind error, %d%s", errno, strerror(errno));
			return false;
		}
		return true;
	}
	// 监听
	bool Listen()
	{
		int ret = ::listen(_sockfd, LISTEN_DEFAULT_BACKLOG);
		if (ret < 0)
		{
			ERR_LOG("listen error, %d%s", errno, strerror(errno));
			return false;
		}
		return true;
	}
	// 向服务端发起链接
	bool Connect(const std::string &ip, uint16_t port)
	{
		struct sockaddr_in addr;
		memset(&addr, 0, sizeof(addr));
		addr.sin_family = AF_INET;
		addr.sin_port = ::htons(port);
		if (inet_pton(AF_INET, ip.c_str(), &addr.sin_addr) != 1)
		{
			ERR_LOG("无效ip, %d%s", errno, strerror(errno));
			return false;
		}
		socklen_t len = sizeof(addr);
		int ret = ::connect(_sockfd, (sockaddr *)&addr, len);
		if (ret < 0)
		{
			ERR_LOG("connect error, %d%s", errno, strerror(errno));
			return false;
		}
		return true;
	}
	// 开启地址端口复用
	void EnableAddressAndPortReuse()
	{
		int opt = 1;
		int ret = ::setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
		if (ret < 0)
		{
			ERR_LOG("地址复用失败, %d%s", errno, strerror(errno));
			return;
		}
		opt = 1;
		ret = ::setsockopt(_sockfd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(int));
		if (ret < 0)
		{
			ERR_LOG("端口复用失败, %d%s", errno, strerror(errno));
			return;
		}
	}
	// 设置非阻塞
	void SetNonBlock()
	{
		int flag = ::fcntl(_sockfd, F_GETFL, 0);
		if (flag < 0)
		{
			ERR_LOG("fcntl error, %d%s", errno, strerror(errno));
			return;
		}
		int ret = ::fcntl(_sockfd, F_SETFL, flag | O_NONBLOCK);
		if (ret < 0)
		{
			ERR_LOG("fcntl error, %d%s", errno, strerror(errno));
			return;
		}
	}

private:
	int _sockfd;
};


#define MAX_EPOLL_EVENTS_DEFAULT 1024
class Poller
{
public:
	Poller()
	{
		_epfd = ::epoll_create(MAX_EPOLL_EVENTS_DEFAULT);
		if (_epfd < 0)
		{
			DEL_LOG("epoll_create error,%d,%s", errno, strerror(errno));
			return;
		}
	}
	~Poller()
	{
		if (_epfd != -1)
		{
			::close(_epfd);
			_epfd = -1;
		}
	}
	// 事件添加修改
	void UpdateEvents(Channel *channel)
	{
		if (!HashChannel(channel))
		{
			// 不存在则添加
			int fd = channel->Fd();
			_channels.insert(std::make_pair(channel->Fd(), channel));
			Update(channel, EPOLL_CTL_ADD);
			return;
		}
		// 存在则修改
		Update(channel, EPOLL_CTL_MOD);
	}
	// 事件移除
	void RemoveEvents(Channel *channel)
	{
		auto it = _channels.find(channel->Fd());
		if (it != _channels.end())
		{
			// 找到，从hash移除
			_channels.erase(channel->Fd());
		}
		// 然后把需要监控的事件移除
		Update(channel, EPOLL_CTL_DEL);
	}
	// 开始监控事件,
	void OpenPoll(std::vector<Channel *> *channel) // 遵循 * 表示输出参数的约定可以使代码更清晰，特别是对大型项目或多人协作项目。这种风格被 Google C++ 风格指南等广泛采用。
	{
		int ret = ::epoll_wait(_epfd, _evs, MAX_EPOLL_EVENTS_DEFAULT, -1);
		if (ret < 0)
		{
			if (errno == EINTR)
			{
				DEL_LOG("被信号中断,%d,%s", errno, strerror(errno));
				return;
			}
			DEL_LOG("epoll_wait errro,%d,%s", errno, strerror(errno));
			return;
		}
		// 根据_evs就绪的事件,设置实际就绪的事件revent，返回活跃链接调用对应的事件回调函数
		for (int i = 0; i < ret; i++)
		{
			auto it = _channels.find(_evs[i].data.fd);
			if (it == _channels.end())
			{
				continue;
			}
			it->second->SetRevent(_evs[i].events);
			channel->push_back(it->second);
		}
	}

private:
	// 对epoll实际添加修改移除事件
	void Update(Channel *channel, int op)
	{
		int fd = channel->Fd();
		struct epoll_event ev;
		ev.data.fd = channel->Fd();
		ev.events = channel->Events();
		int ret = ::epoll_ctl(_epfd, op, fd, &ev);
		if (ret < 0)
		{
			ERR_LOG("epoll_ctl error,%d,%s", errno, strerror(errno));
			return;
		}
	}
	// 事件是否存在
	bool HashChannel(Channel *channel)
	{
		auto it = _channels.find(channel->Fd());
		if (it == _channels.end())
		{
			// 没找到
			return false;
		}
		return true;
	}

private:
	int _epfd = -1;
	struct epoll_event _evs[MAX_EPOLL_EVENTS_DEFAULT];
	std::unordered_map<int, Channel *> _channels; // 把需要监控的描述符添加进来，事件触发时的快速查找，，并设置就绪事件
};


// 使用环形缓冲区(60槽位)实现时间轮
// 通过智能指针管理任务生命周期
// 利用析构函数统一处理任务执行和清理
// 支持任务刷新和取消机制
// 特别适合非活跃连接超时处理场景

// 封装定时任务的唯一标识、超时时间、执行逻辑和取消状态
// 通过智能指针管理生命周期，析构时自动清理相关资源
class EventLoop;
using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void()>;
class TimerTask // 定时任务的载体，封装任务逻辑和生命周期控制
{
public:
	TimerTask(uint64_t id, uint32_t timeout, const TaskFunc &task)
		: _id(id), _timeout(timeout), _task(task), _cancel(false)
	{
	}
	~TimerTask()
	{
		if (_cancel == false)
			_task();	// 取消定时任务销毁要在这任务模块完成，如果在时间轮完成还不是相当于销毁任务
		_releasetack(); // 把被weak_ptr管理起来的shared_ptr从_clone中移除，只有shared_ptr计数为0时才会进入析构函数
	}
	void SetReleaseTask(const ReleaseFunc &releasetack)
	{
		_releasetack = releasetack;
	}
	void Cancel() { _cancel = true; }
	int TimeOut() { return _timeout; }

private:
	uint64_t _id;			  // 定时任务id
	uint32_t _timeout;		  // 超时时间
	bool _cancel;			  // false表示不取消非活跃链接销毁，true表示取消
	TaskFunc _task;			  // 定时器对象要执行的定时任务
	ReleaseFunc _releasetack; // //用于删除TimerWheel中保存的定时器对象信息
};

// 维护一个环形时间轮结构，实现任务的定时调度
// 使用智能指针管理任务生命周期，避免循环引用
// 支持任务的添加、刷新、执行和取消操作
using SharTask = std::shared_ptr<TimerTask>;
using WeakTask = std::weak_ptr<TimerTask>;
class TimerWheel // 时间轮管理器，负责任务的调度、执行和管理
{
public:
	TimerWheel(EventLoop *loop)
		: _tick(0), _capacity(60), _wheel(_capacity), _loop(loop), _timerfd(CreateTimerfd()), _timer_channel(new Channel(_loop, _timerfd))
	{
		_timer_channel->SetReadCallback(std::bind(&TimerWheel::OnTimer, this));
		_timer_channel->EnableReadableEvent();
	}
	void TaskAdd(uint64_t id, uint32_t timeout, const TaskFunc &task);
	void RefreshTask(uint64_t id);
	void TaskCancel(uint64_t id);
	bool hashtimer(uint64_t id)
	{
		auto it = _clone.find(id);
		if (it == _clone.end())
		{
			DEL_LOG("没有找到");
			return false;
		}
		return true;
	}

private:
	void Remove(uint64_t id)
	{
		auto it = _clone.find(id);
		if (it != _clone.end())
		{
			// 找到了 进行移除
			_clone.erase(id);
		}
	}
	int CreateTimerfd()
	{
		int timerfd = ::timerfd_create(CLOCK_MONOTONIC, 0);
		if (timerfd < 0)
		{
			ERR_LOG("timerfd_create error,%d,%s", errno, strerror(errno));
			abort();
		}
		struct itimerspec n;
		n.it_value.tv_sec = 1;
		n.it_value.tv_nsec = 0;
		n.it_interval.tv_sec = 1;
		n.it_interval.tv_nsec = 1;
		int ret = ::timerfd_settime(timerfd, 0, &n, nullptr);
		if (ret < 0)
		{
			ERR_LOG("timerfd_settime error,%d,%s", errno, strerror(errno));
			abort();
		}
		return timerfd;
	}
	int ReadTImerfd()
	{
		uint64_t timed = 0;
		ssize_t n = ::read(_timerfd, &timed, sizeof(timed));
		if (n < 0)
		{
			ERR_LOG("timerfd read error,%d,%s", errno, strerror(errno));
			abort();
		}
		return timed;
	}
	void RunTimerTask() // 这个函数应该每秒钟被执行一次，相当于秒针向后走了一步
	{
		_tick = (_tick + 1) % _capacity;
		_wheel[_tick].clear(); // 清空指定位置的数组，就会把数组中保存的所有管理定时器对象的shared_ptr释放掉
	}
	// 	考虑以下场景：
	//  1.定时器每 1 秒触发一次事件。
	//  2.某次事件处理耗时 3 秒，期间定时器超时 3 次。
	//  3.当程序恢复处理定时器事件时，ReadTimefd() 返回 times = 3，表示积压了 3 次超时。
	//  4.通过循环 RunTimerTask() 3 次，时间轮指针 _tick 会连续移动 3 格，保持与实际时间同步。
	//  若不处理积压次数，时间轮指针会滞后，导致定时任务延迟执行或丢失。
	void OnTimer()
	{
		// 获取超时次数
		int n = ReadTImerfd();
		// 确保即使系统繁忙导致定时器事件处理延迟，也能通过批量处理恢复时间轮的准确性
		for (int i = 0; i < n; i++)
		{
			RunTimerTask();
		}
	}
	void TaskAddInLoop(uint64_t id, uint32_t timeout, const TaskFunc &task) // 添加定时任务
	{
		SharTask pt(new TimerTask(id, timeout, task));
		pt->SetReleaseTask(std::bind(&TimerWheel::Remove, this, id)); // 插入 释放保存的定时任务 函数，sherad_ptr管理的定时任务计数为0时，进行释放执行析构函数
		int ti = (_tick + timeout) % _capacity;
		_wheel[ti].push_back(pt);  // 把任务添加到时间轮去
		_clone[id] = WeakTask(pt); // 同时用weak_ptr把shared_ptr管理起来
	}
	void RefreshTaskInLoop(uint64_t id) // 刷新定时任务
	{
		auto it = _clone.find(id);
		if (it == _clone.end())
		{
			// 没找到 直接返回
			return;
		}
		SharTask pt = it->second.lock(); // 找到保存的定时任务，对该任务进行生成一个shared_ptr,此时引用计数++
		if (!pt)
		{					  // lock() 失败处理
			_clone.erase(it); // 清理无效 weak_ptr
			return;
		}
		int del = pt->TimeOut(); // 获取超时时间
		int ti = (_tick + del) % _capacity;
		_wheel[ti].push_back(pt); // 将任务移动到新的时间点
	}
	void TaskCancelInLoop(uint64_t id) // 取消定时任务销毁
	{
		auto it = _clone.find(id);
		if (it == _clone.end())
		{
			// 没找到 直接返回
			return;
		}
		SharTask pt = it->second.lock();
		if (pt)
			pt->Cancel(); // lock成功进行取消
		_clone.erase(it); // 仅设置 _cancel 而不主动移除 _clone 记录，会导致 _clone 中残留无效数据
						  // 如果后续调用 RefreshTack(id)，会尝试刷新一个已取消的任务（虽然 _cancel = true，但逻辑上不应该再处理）
	}

private:
	int _tick;									   // 每秒移动后的位置，执行该位置的定时任务
	int _capacity;								   // 时间轮的大小
	std::vector<std::vector<SharTask>> _wheel;	   // 时间轮，里面装的是用Sherad_ptr管理起来的定时任务
	std::unordered_map<uint64_t, WeakTask> _clone; // 保存每一个定时任务对象，但是用weak_ptr进行管理sherad_ptr对象，
												   // 防止循环引用，每个定时任务执行完毕后，要进行释放移除
	EventLoop *_loop;
	int _timerfd; // 定时器描述符，可读事件回调就是读取定时器，执行任务
	std::unique_ptr<Channel> _timer_channel;
};


// 保证每一个链接都在一个线程中，但是如果在多线程中，分摊了这个链接的任务，而这写任务有封装的Send操作，而这封装的Send操作是共享资源，
// 会引发线程安全，所以，把这些操作压入任务队列中，然后对任务队列加锁，然后统一执行队列操作
using Functor = std::function<void()>;

class EventLoop
{
private:
	void RunAllTast()
	{
		std::vector<Functor> tmp;
		{
			std::unique_lock<std::mutex> lock(_mutex);
			_tasks.swap(tmp);
		}
		for (auto &e : tmp)
		{
			e();
		}
	}
	// 不需要eventloop内操作，不需要this
	static int CreateEventfd()
	{
		int ret = ::eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
		if (ret < 0)
		{
			ERR_LOG("eventfd error,%d,%s", errno, strerror(errno));
			abort();
		}
		return ret;
	}
	// 读进行消费，内容置为0
	void ReadEventfd()
	{
		uint64_t val = 0;
		int ret = ::read(_event_fd, &val, sizeof(val));
		if (ret < 0)
		{
			// EINTR -- 被信号打断； EAGAIN -- 表⽰⽆数据可读
			if (errno == EINTR || errno == EAGAIN)
			{
				return;
			}
			ERR_LOG("eventfd read error,%d,%s", errno, strerror(errno));
			abort();
		}
		return;
	}
	// 写进行唤醒事件描述符
	void WeakUpEventFd()
	{
		uint64_t val = 1;
		int ret = ::write(_event_fd, &val, sizeof(val));
		if (ret < 0)
		{
			if (errno == EINTR)
			{
				return;
			}
			ERR_LOG("eventfd write error,%d,%s", errno, strerror(errno));
			abort();
		}
	}

public:
	EventLoop()
		: _timer_wheel(this), _thread_id(std::this_thread::get_id()), _event_fd(CreateEventfd()), _event_channel(new Channel(this, _event_fd))
	{
		_event_channel->SetReadCallback(std::bind(&EventLoop::ReadEventfd, this));
		_event_channel->EnableReadableEvent();
	}
	void Start()
	{
		while (1)
		{
			// 事件监控  就绪事件处理，执行任务
			std::vector<Channel *> active;
			poller.OpenPoll(&active);
			for (auto &e : active)
			{
				e->HandlerEvent();
			}
			RunAllTast();
		}
	}
	// 判断当前线程是否是EventLoop对应的线程
	bool IsInLoop()
	{
		return (std::this_thread::get_id() == _thread_id);
	}
	void AssertInLoop()
	{
		assert(_thread_id == std::this_thread::get_id());
	}
	// 判断当前任务是不是在当前线程中，如果在直接执行，不在则压入任务队列
	void RunInLoop(const Functor &cd)
	{
		if (IsInLoop())
		{
			return cd(); // 要直接返回，不然又插入队列，此时Channel被销毁后，队列里面又有任务，执行任务就会报错
		}
		return QueueInLoop(cd);
	}
	// 把任务压入队列
	void QueueInLoop(const Functor &cd)
	{
		// 对队列进行操作要进行加锁
		{
			std::unique_lock<std::mutex> lock(_mutex);
			_tasks.push_back(cd);
		}
		// 把任务插入队列中，有有可能epoll_wait等待就绪事件可能发生阻塞要进行唤醒
		WeakUpEventFd();
	}
	// 添加/修改描述符监控
	void UpdateEvents(Channel *channel)
	{
		return poller.UpdateEvents(channel);
	}
	// 移除描述符监控
	void RemoveEvents(Channel *channel)
	{
		return poller.RemoveEvents(channel);
	}
	// 添加定时任务
	void TaskAdd(uint64_t id, uint32_t timeout, const TaskFunc &task)
	{
		_timer_wheel.TaskAdd(id, timeout, task);
	}
	void RefreshTask(uint64_t id)
	{
		_timer_wheel.RefreshTask(id);
	}
	void TaskCancel(uint64_t id)
	{
		_timer_wheel.TaskCancel(id);
	}
	bool hashTimer(uint64_t id)
	{
		return _timer_wheel.hashtimer(id);
	}

private:
	Poller poller;
	TimerWheel _timer_wheel;
	std::thread::id _thread_id;				 // eventloop所处线程id
	int _event_fd;							 // eventfd唤醒事件监控
	std::unique_ptr<Channel> _event_channel; // 管理eventfd事件监控
	std::vector<Functor> _tasks;			 // 任务池
	std::mutex _mutex;
};

void Channel::Remove()
{
	_loop->RemoveEvents(this);
}

void Channel::Update()
{
	_loop->UpdateEvents(this);
}
void TimerWheel::TaskAdd(uint64_t id, uint32_t timeout, const TaskFunc &task)
{
	_loop->RunInLoop(std::bind(&TimerWheel::TaskAddInLoop, this, id, timeout, task));
}
void TimerWheel::RefreshTask(uint64_t id)
{
	_loop->RunInLoop(std::bind(&TimerWheel::RefreshTaskInLoop, this, id));
}
void TimerWheel::TaskCancel(uint64_t id)
{
	_loop->RunInLoop(std::bind(&TimerWheel::TaskCancelInLoop, this, id));
}



class Any
{
private:
	class holder
	{
	public:
		virtual ~holder() {}
		virtual const std::type_info &type() = 0;
		virtual holder *clone() = 0;
	};
	template <class T>
	class placeholder : public holder
	{
	public:
		placeholder(const T &val)
			: _val(val)
		{
		}
		virtual const std::type_info &type() // 获取数据类型
		{
			return typeid(T);
		}
		virtual holder *clone() // 针对当前类型对象，克隆一个新的子类对象
		{
			return new placeholder(_val);
		}

	public:
		T _val;
	};
	Any &swap(Any &other)
	{
		std::swap(_content, other._content);
		return *this;
	}

public:
	Any()
		: _content(nullptr)
	{
	}
	template <class T>
	Any(const T &val)
		: _content(new placeholder<T>(val))
	{
	}
	Any(const Any &other)
		: _content(other._content ? other._content->clone() : nullptr)
	{
	}
	~Any()
	{
		delete _content;
	}
	template <class T>
	T *get() // // 返回子类对象保存的数据的指针
	{
		// 要保证想获取的数据类型和数据保存的数据类型一致
		assert(typeid(T) == _content->type());
		return &((placeholder<T> *)_content)->_val;
	}
	template <class T>
	Any &operator=(const T &val) // 为赋值其他类型的数据
	{
		Any(val).swap(*this); // 创建临时对象，出作用域就会销毁原本的指针
		return *this;
	}
	Any &operator=(const Any &other) // 为赋值另一个Any的数据
	{
		Any(other).swap(*this);//临时对象离开作用域时，其析构函数 ~Any() 会调用 delete _content，释放的是当前对象原来持有的资源。
		return *this;
	}

private:
	holder *_content;
};



// 管理链接的模块
// DISCONECTED -- 连接关闭状态；   CONNECTING -- 连接建立成功-待处理状态
// CONNECTED -- 连接建立完成，各种设置已完成，可以通信的状态；  DISCONNECTING -- 待关闭状态
typedef enum
{
	DISCONNECTED, // 连接关闭状态
	CONNECTING,	  // 连接建立成功-待处理状态
	CONNECTED,	  // 连接建立完成，各种设置已完成，可以通信的状态
	DISCONNECTING // 待关闭状态
} Connstate;

class Connection;
using Ptrconnection = std::shared_ptr<Connection>;
using ConnectCallback = std::function<void(const Ptrconnection &)>;
using MessageCallback = std::function<void(const Ptrconnection &, Buffer *)>;
using CloseCallback = std::function<void(const Ptrconnection &)>;
using AnyEventCallback = std::function<void(const Ptrconnection &)>;

class Connection : public std::enable_shared_from_this<Connection>
{
private:
	/*五个channel的事件回调函数*/
	void HandleRead()
	{
		char buff[65536];
		ssize_t ret = _socket.RecvNonBlock(buff, 65535);
		if (ret < 0)
		{
			// 出错了，不能直接关闭
			ERR_LOG("recv error,%d,%s", errno, strerror(errno));
			return ShutdownInLoop();
		}
		// 这里的等于0表示的是没有读取到数据，而并不是连接断开了，连接断开返回的是-1
		// 将数据放入输入缓冲区,写入之后顺便将写偏移向后移动
		_in_buffer.WriteAndPush(buff, ret);
		// 2. 调用message_callback进行业务处理
		if (_in_buffer.ReadableSize() > 0)
		{
			return _message_callback(shared_from_this(), &_in_buffer);
		}
	}
	void HandleWrite()
	{
		ssize_t ret = _socket.SendNonBlock(_out_buffer.ReadPosition(), _out_buffer.ReadableSize());
		if (ret < 0)
		{
			ERR_LOG("send error,%d,%s", errno, strerror(errno));
			// 发送错误就该关闭连接了，并且处理接受缓冲区数据
			if (_in_buffer.ReadableSize() > 0)
			{
				_message_callback(shared_from_this(), &_in_buffer);
			}
			// 然后释放
			return Release();
		}
		// 千万不要忘了，将读偏移向后移动
		_out_buffer.MoveReadOffset(ret);
		if (_out_buffer.ReadableSize() == 0)
		{
			// 关闭写事件监控
			_channels.CloseWriteableEvent();
			if (_state == DISCONNECTING)
			{
				return Release();
			}
		}
		return;
	}
	void HandleError()
	{
		return HandleClose();
	}
	void HandleClose()
	{
		if (_in_buffer.ReadableSize() > 0)
		{
			_message_callback(shared_from_this(), &_in_buffer);
		}
		return Release();
	}
	void HandleEvent()
	{
		if (_enable_inactive_release == true)
		{
			_loop->RefreshTask(_conn_id);
		}
		if (_event_callback)
		{
			_event_callback(shared_from_this());
		}
	}
	// 连接获取之后，所处的状态下要进行各种设置（启动读监控,调用回调函数）
	void EstablishInLoop()
	{
		assert(_state == CONNECTING);
		_state = CONNECTED;
		// 一旦启动读事件监控就有可能会立即触发读事件，如果这时候启动了非活跃连接销毁,所有放入任务队列中
		_channels.EnableReadableEvent();
		if (_connect_callback)
		{
			_connect_callback(shared_from_this());
		}
	}
	// 这个接口并不是实际的发送接口，而只是把数据放到了发送缓冲区，启动了可写事件监控
	void SendInLoop(Buffer &buff)
	{
		if (_state == DISCONNECTED)
		{
			return;
		}
		_out_buffer.WriteBufferAndPush(buff);
		if (_channels.Writeable() == false)
		{
			_channels.EnableWriteableEvent(); // 会触发「写事件」，告诉程序：“可以调用 write/send 发数据了”。
		}
	}
	// 这个关闭操作并非实际的连接释放操作，需要判断还有没有数据待处理，待发送
	void ShutdownInLoop()
	{
		_state = DISCONNECTING;
		if (_in_buffer.ReadableSize() > 0)
		{
			_message_callback(shared_from_this(), &_in_buffer);
		}
		// 要么就是写入数据的时候出错关闭，要么就是没有待发送数据，直接关闭
		if (_out_buffer.ReadableSize() > 0)
		{
			if (_channels.Writeable() == false)
			{
				_channels.EnableWriteableEvent();
			}
		}
		if (_out_buffer.ReadableSize() == 0)
		{
			DEL_LOG("Release");
			return Release();
		}
	}
	// 真正的释放接口
	void ReleaseInLoop()
	{
		// 1. 修改连接状态，将其置为DISCONNECTED
		_state = DISCONNECTED;
		// 2. 移除连接的事件监控
		_channels.Remove();
		// 3. 关闭描述符
		_socket.Close();
		// 4. 如果当前定时器队列中还有定时销毁任务，则取消任务
		if (_loop->hashTimer(_conn_id))
		{
			CancelInactiveReleaseInLoop();
		}
		// 5. 调用关闭回调函数，避免先移除服务器管理的连接信息导致Connection被释放，再去处理会出错，因此先调用用户的回调函数
		if (_close_callback)
		{
			_close_callback(shared_from_this());
		}
		// 移除服务器内部管理的连接信息
		if (_server_closed_callback)
		{
			_server_closed_callback(shared_from_this());
		}
	}
	// 启动非活跃链接销毁
	void EnableInactiveReleaseInLoop(int sec)
	{
		// 1. 将判断标志 _enable_inactive_release 置为true
		_enable_inactive_release = true;
		// 2. 如果当前定时销毁任务已经存在，那就刷新延迟一下即可
		if (_loop->hashTimer(_conn_id))
		{
			return _loop->RefreshTask(_conn_id);
		}
		// 3. 如果不存在定时销毁任务，则新增
		_loop->TaskAdd(_conn_id, sec, std::bind(&Connection::Release, this));
	}
	// 取消非活跃链接销毁
	void CancelInactiveReleaseInLoop()
	{
		_enable_inactive_release = false;
		if (_loop->hashTimer(_conn_id))
		{
			_loop->TaskCancel(_conn_id);
		}
	}
	//
	void UpgradeInLoop(const Any &context,
					   const ConnectCallback &conn,
					   const MessageCallback &mes,
					   const CloseCallback &close,
					   const AnyEventCallback &event)
	{
		_context = context;
		_connect_callback = conn;
		_message_callback = mes;
		_close_callback = close;
		_event_callback = event;
	}

public:
	Connection(uint64_t id, int sockfd, EventLoop *loop)
		: _conn_id(id), _sockfd(sockfd), _enable_inactive_release(false),
		  _loop(loop), _state(CONNECTING), _socket(_sockfd), _channels(_loop, _sockfd)
	{
		_channels.SetReadCallback(std::bind(&Connection::HandleRead, this));
		_channels.SetWriteCallback(std::bind(&Connection::HandleWrite, this));
		_channels.SetCloseCallback(std::bind(&Connection::HandleClose, this));
		_channels.SetErrorCallback(std::bind(&Connection::HandleError, this));
		_channels.SetEventCallback(std::bind(&Connection::HandleEvent, this));
	}
	~Connection()
	{
		INF_LOG("RELEASE CONNECTION:%p", this);
	}
	// 获取管理的文件描述符
	int Fd()
	{
		return _sockfd;
	}
	int Id()
	{
		return _conn_id;
	}
	// 是否处于CONNECTED状态
	bool Connected()
	{
		return _state == CONNECTED;
	}
	// 设置上下文--连接建立完成时进行调用
	void SetContext(const Any &context)
	{
		_context = context;
	}
	// 获取上下文，返回的是指针
	Any *GetContext()
	{
		return &_context;
	}
	void SetConnectCallback(const ConnectCallback &cd)
	{
		_connect_callback = cd;
	}
	void SetMessageCallback(const MessageCallback &cd)
	{
		_message_callback = cd;
	}
	void SetCloseCallback(const CloseCallback &cd)
	{
		_close_callback = cd;
	}
	void SetAnyEventCallback(const AnyEventCallback &cd)
	{
		_event_callback = cd;
	}
	void SetServeCloseCallback(const CloseCallback &cd)
	{
		_server_closed_callback = cd;
	}
	// 建立链接后进行各种设置
	void Establish()
	{
		_loop->RunInLoop(std::bind(&Connection::EstablishInLoop, this));
	}
	// 发生数据，将数据发送到缓冲区中，启动写事件监控
	void Send(const char *date, size_t len)
	{
		// 外界传⼊的data，可能是个临时的空间，我们现在只是把发送操作压⼊了任务池，有可能并没有被⽴即执⾏
        // 因此有可能执⾏的时候，data指向的空间有可能已经被释放了。
		Buffer buff;
		buff.WriteAndPush(date,len);
		_loop->RunInLoop(std::bind(&Connection::SendInLoop, this, buff));
	}
	// 关闭链接，并不是真正的关闭链接，因为需要判断关闭连接前有没有数据待发送处理
	void Shutdown()
	{
		_loop->RunInLoop(std::bind(&Connection::ShutdownInLoop, this));
	}
	// 真正释放
	void Release()
	{
		// 放入任务队列是因为，如果链接释放了，还要进行操作而导致崩溃，所以要压入队列，
		// 1234，如果1是定时销毁任务，释放了，就会把234对应链接释放，在进行234事件操作就会引发崩溃
		_loop->QueueInLoop(std::bind(&Connection::ReleaseInLoop, this));
	}
	// 启动非活跃销毁
	void EnableInactiveRelease(int sec)
	{
		_loop->RunInLoop(std::bind(&Connection::EnableInactiveReleaseInLoop, this, sec));
	}
	// 取消非活跃销毁
	void CancelInactiveRelease()
	{
		_loop->RunInLoop(std::bind(&Connection::CancelInactiveReleaseInLoop, this));
	}
	// 切换协议
	// 切换协议---重置上下文以及阶段性回调处理函数 -- 而是这个接口必须在EventLoop线程中立即执行
	// 防备新的事件触发后，处理的时候，切换任务还没有被执行--会导致数据使用原协议处理了
	void Upgrade(const Any &context,
				 const ConnectCallback &conn,
				 const MessageCallback &mes,
				 const CloseCallback &close,
				 const AnyEventCallback &event)
	{
		// 必须保证在当前线程，
		_loop->AssertInLoop();
		_loop->RunInLoop(std::bind(&Connection::UpgradeInLoop, this, context, conn, mes, close, event));
	}

private:
	uint64_t _conn_id;			   // 链接的唯一id
	int _sockfd;				   // 链接管理的文件描述符
	Socket _socket;				   // 套接字操作管理
	bool _enable_inactive_release; // 是否启动非活跃链接销毁 默认为false
	Connstate _state;			   // 链接所处的状态
	EventLoop *_loop;			   // 连接所关联的一个EventLoop
	Channel _channels;			   // 链接的事件管理
	Buffer _in_buffer;			   // 输入缓冲区，从socket接受的数据放入输入缓冲区
	Buffer _out_buffer;			   // 输出缓冲区，存放要发送的数据
	Any _context;				   // 请求的接受处理上下文
	ConnectCallback _connect_callback;
	MessageCallback _message_callback;
	CloseCallback _close_callback;
	AnyEventCallback _event_callback;
	/*组件内的连接关闭回调--组件内设置的，因为服务器组件内会把所有的连接管理起来，一旦某个连接要关闭*/
	/*就应该从管理的地方移除掉自己的信息*/
	CloseCallback _server_closed_callback;
};


// 将线程与EventLoop对应起来
class LoopThread
{
private:
	// 实例化EventLoop对象，唤醒有可能阻塞在_cond上的线程，并且启动loop
	void ThreadEntry()
	{
		EventLoop loop;
		{
			std::unique_lock<std::mutex> lock(_mutex);
			_loop = &loop;
			_cond.notify_all();
		}
		loop.Start();
	}

public:
	// 创建线程，设置线程入口函数
	LoopThread()
		: _loop(nullptr), _thread(std::thread(&LoopThread::ThreadEntry, this))
	{
	}
	// 返回当前线程对应的EventLoop指针
	EventLoop *GetLoop()
	{
		EventLoop *loop = nullptr;
		{
			std::unique_lock<std::mutex> lock(_mutex); // 加锁
			_cond.wait(lock, [&]()
					   { return _loop != nullptr; }); // 如果为nullptr就一直阻塞
			loop = _loop;
		}
		return loop;
	}

private:
	std::mutex _mutex;			   // 互斥锁
	std::condition_variable _cond; // 条件变量
	EventLoop *_loop;			   // EventLoop指针变量，需要在线程中实例化
	std::thread _thread;		   // EventLoop对应的线程
};



// 争对LoopThread设计线程池
class LoopThreadPool
{
public:
	LoopThreadPool(EventLoop *loop)
		: _thread_count(0), _next_loop_idx(0), _baseloop(loop)
	{
	}
	// 设置从属线程数量
	void SetThreadCount(int count)
	{
		_thread_count = count;
	}
	// 创建所有从属线程
	void Create()
	{
		if (_thread_count > 0)
		{
			_threads.resize(_thread_count);
			_loops.resize(_thread_count);
			for (int i = 0; i < _thread_count; i++)
			{
				_threads[i] = new LoopThread();
				_loops[i] = _threads[i]->GetLoop();
			}
		}
		return;
	}
	// 分配EventLoop
	EventLoop *NextLoop()
	{
		if (_thread_count == 0)
		{
			return _baseloop;
		}
		_next_loop_idx = (_next_loop_idx + 1) % _thread_count;
		return _loops[_next_loop_idx];
	}

private:
	int _thread_count;					// 线程数量
	int _next_loop_idx;					// 分配出去的eventLoop的指针数组下标
	EventLoop *_baseloop;				// 主线程
	std::vector<LoopThread *> _threads; // 保存所有的LoopThread对象
	std::vector<EventLoop *> _loops;	// 从属线程大于0，则从_loop中进行线程EventLoop分配
};


using AcceptorCallback = std::function<void(int)>;

class Acceptor
{
private:
	void HandleRead()
	{
		int newfd = _socket.Accept();
		if(newfd < 0)
		{
			return;
		}
		_acceptor_callback(newfd);
	}
	int CreateServer(uint64_t port)
	{
		int ret = _socket.CreateTcpServer(port);
		assert(ret == true);
		return _socket.Fd();
	}
public:
	// 1.创建监听套接字
	// 2.启动读事件监控
	// 3.事件触发后获取新链接
	// 4.为新连接创建Connection进行管理
	Acceptor(EventLoop *loop,uint64_t port)
		:_socket(CreateServer(port))
		,_loop(loop)
		,_channels(_loop,_socket.Fd())
	{
		/*不能将启动读事件监控，放到构造函数中，必须在设置回调函数后，再去启动*/
        /*否则有可能造成启动监控后，立即有事件，处理的时候，回调函数还没设置：新连接得不到处理，且资源泄漏*/
		_channels.SetReadCallback(std::bind(&Acceptor::HandleRead,this));
		// _channels.EnableReadableEvent();
	}
	void SetAcceptorCallback(const AcceptorCallback &cb)
	{
		_acceptor_callback = cb;
	}
	void Listen()
	{
		_channels.EnableReadableEvent();
	}
private:
	Socket _socket;
	EventLoop *_loop;
	Channel _channels;
	AcceptorCallback _acceptor_callback;
};

using Functor = std::function<void()>;
using ConnectCallback = std::function<void(const Ptrconnection &)>;
using MessageCallback = std::function<void(const Ptrconnection &, Buffer *)>;
using CloseCallback = std::function<void(const Ptrconnection &)>;
using AnyEventCallback = std::function<void(const Ptrconnection &)>;
class TcpServer
{
private:
	// 添加定时销毁任务
	void RunAfterInLoop(int delay, const Functor &task)
	{
		_next_id++;
		_baseloop.TaskAdd(_next_id, delay, task);
	}
	// 为新连接构造一个Connection进行管理
	void NewConnection(int fd)
	{
		_next_id++;
		Ptrconnection ch(new Connection(_next_id, fd, _pool.NextLoop()));
		ch->SetMessageCallback(_message_callback);
		ch->SetCloseCallback(_close_callback);
		ch->SetConnectCallback(_connect_callback);
		ch->SetAnyEventCallback(_event_callback);
		ch->SetServeCloseCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
		if (_enable_inactive_release)
			ch->EnableInactiveRelease(_timeout);
		ch->Establish();
		_conns.insert(std::make_pair(_next_id, ch));
	}
	void RemoveConnectionInLoop(const Ptrconnection &conn)
	{
		int id = conn->Id();
		auto it = _conns.find(id);
		if (it != _conns.end())
		{
			_conns.erase(id);
		}
	}
	// 从_conns中移除对应的Connection链接
	void RemoveConnection(const Ptrconnection &conn)
	{
		_baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));
	}

public:
	TcpServer(int port)
		: _next_id(0), _accept(&_baseloop, port), _pool(&_baseloop)
	{
		_accept.SetAcceptorCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));
	}
	void SetConnectCallback(const ConnectCallback &cd)
	{
		_connect_callback = cd;
	}
	void SetMessageCallback(const MessageCallback &cd)
	{
		_message_callback = cd;
	}
	void SetCloseCallback(const CloseCallback &cd)
	{
		_close_callback = cd;
	}
	void SetAnyEventCallback(const AnyEventCallback &cd)
	{
		_event_callback = cd;
	}
	// 启动非活跃链接销毁
	void EnableInactiveRelease(int timeout)
	{
		_timeout = timeout;
		_enable_inactive_release = true;
	}
	// 设置线程数量
	void SetThreadCount(int count)
	{
		_pool.SetThreadCount(count);
	}
	// 添加定时任务
	void RunAfter(int delay, const Functor &task)
	{
		_baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, delay, task));
	}
	// 启动
	void Start()
	{
		_pool.Create();
		_accept.Listen();
		_baseloop.Start();
	}

private:
	uint64_t _next_id;
	int _timeout;										// 超时时间
	bool _enable_inactive_release;						// 是否启动非活跃链接销毁
	EventLoop _baseloop;								// 这是主线程的EventLoop对象，负责监听事件的处理
	Acceptor _accept;									// 这是监听套接字的管理对象
	LoopThreadPool _pool;								// 这是从属EventLoop线程池
	std::unordered_map<uint64_t, Ptrconnection> _conns; // 保存管理所有连接对应的shared_ptr对象

	ConnectCallback _connect_callback;
	MessageCallback _message_callback;
	CloseCallback _close_callback;
	AnyEventCallback _event_callback;
};

// 忽略 SIGPIPE 是网络编程常见手段，防止因对端断开连接后继续写操作导致程序异常终止。
class NetWork
{
public:
	NetWork()
	{
		DEL_LOG("SIGPIPE init");
		signal(SIGPIPE, SIG_IGN);
	}
};

static NetWork net;